今日文章目錄
- 前言
- 參考文章
之前提到,useState
方法可以讓我在component
內部操作資料狀態。
今天來談談另外一個常用到的方法:useEffect
。
這裡的Effect
指的是「side-effect 副作用」。
也就是說 useEffect
是用來處理React component
職責以外的額外動作。
(舉手提問) React component的職責是什麼?
答:在使用者介面上直接操作資料狀態及回傳節點。
就是之前說的:實現 相關UI與邏輯 群組化(component
),並回傳React element(JSX
)。
(補充後面動作:節點透過ReactDOM.render()
放入html檔,瀏覽器解析成 DOM tree,然後渲染成網頁畫面。)
額外動作好比:call api拿資料,直接操作原始DOM(不經過React component
),登入 token...等,不是component
的主要職責,但需要執行的動作,都可能使用到 useEffect
。
useEffect(function,[state1, props2...])
useEffect()
接收兩個參數:
function
: 執行動作的函式。useEffect()
會寫在component
裡面,所以函式內也可以操作state
[state1, props2...]
: 用來比對state
或props
狀態,如果狀態有變,執行function
,比對項目如果有多組,只要一個有變,function
就會執行。這裡要提到兩個重要概念:React render 順序、dependency比對標準
component
、useEffect()
內、JSX
內。可以看到component
會先屢行它的主要職責,才進行額外行動:useEffect是在component渲染完後才執行。
[dependency]
,程式執行的情況。OK,那如果dependency要比對物件型別呢?
useEffect(() => console.log("useEffect !"),[{id: 1, name: "Joanna"}])
這會出現一個狀況:如果物件內的屬性改值,但 useEffect()
比對物件的位址不變,導致不會執行動作。
如果要解決這樣的問題,有幾個解決方法:
const [obj, setObj] = useState({id: 1, name: "Joanna"});
useEffect(() => console.log("useEffect !"),[obj.name])
useEffect()
比對物件的位址,那我改位址可以吧!const [obj, setObj] = useState({id: 1, name: "Joanna"});
useEffect(() => console.log("useEffect !"),[obj])
// 改值:
setObj({...obj, name: "David"})